package com.nti56.springboot.aspect;

import com.nti56.springboot.annotation.DataAuth;
import com.nti56.springboot.exception.MyRuntimeException;
import com.nti56.springboot.model.User;
import com.nti56.springboot.service.OrganizationService;
import com.nti56.springboot.utils.Constant;
import com.nti56.springboot.utils.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
   * 数据权限切面
 * @author szq
 *
 */
@Aspect
@Component
public class DataAuthAspect {
	
	private static final Logger logger = LoggerFactory.getLogger(DataAuthAspect.class);

	@Autowired
	private OrganizationService organizationService;
	
	@Pointcut("@annotation(com.nti56.springboot.annotation.DataAuth)")
    public void dataAuthPointcut(){

    }

    @Before("dataAuthPointcut()")
    public void dataAuth(JoinPoint joinPoint) throws Throwable{
        //获取方面第一个参数
    	if(joinPoint.getArgs() == null || joinPoint.getArgs().length == 0) {
    		throw new MyRuntimeException("数据权限过滤，注解的方法不能无参！");
    	}
        Object params = joinPoint.getArgs()[0];
        //如果参数为Map类型
        if(params != null && params instanceof Map){
        	if(RequestContextHolder.getRequestAttributes() != null) {
        		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                User user = (User) request.getSession().getAttribute(Constant.SESSION_USER_KEY);
                if(!user.getUserName().equals(Constant.SYSTEM_SUPER_ADMIN_NAME)){
                   ((Map) params).put("dataAuthSql",dataAuthSql(joinPoint));
                }
        	}
        }else {
        	if(params != null  && !(params instanceof Map)) {
        		 throw new MyRuntimeException("数据权限过滤，需要查询方法的第一个参数为Map类型");
        	}
        }
    }

    public String dataAuthSql(JoinPoint joinPoint){
    	String inParam = this.getInParam();
        //获取目标方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //通过方法签名，获取数据过滤注解
        DataAuth annotation = signature.getMethod().getAnnotation(DataAuth.class);
        //通过注解获取别名
        String columnName = annotation.columnName();       
        StringBuilder dataAuthSql = new StringBuilder();
        dataAuthSql.append(columnName);
        dataAuthSql.append(" in (");
        dataAuthSql.append(inParam);
        dataAuthSql.append(")");
        return dataAuthSql.toString();
    }
    
    /**
            *  获取自身加子机构编码，转换成 数据库in语句的形式
     * @return
     */
    private String getInParam(){
    	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        User user = (User) request.getSession().getAttribute(Constant.SESSION_USER_KEY);
        List<String> list = (List<String>)request.getSession().getAttribute(Constant.SESSION_USER_DATA_ORG);
        List<String> orgCodes = new ArrayList<String>();
        if(list == null || list.size()==0) {
        	//默认用户部门
        	orgCodes = organizationService.getSubOrgCodes(user.getOrgId());
        }else {
        	//从授权机构里获取
        	orgCodes = list;
        }    	
    	String str = StringUtils.join(orgCodes.toArray(), ",");
    	String inParam = StringUtil.toInParam(str);
    	logger.info("inParam:"+inParam);
    	return inParam;
    }
    
}
